<template>
    <div class="box">
         <div id="webgl"  ref="webgl"></div>
    </div>
</template>
<script setup>
// 引入three.js
import * as THREE from 'three';
// 引入轨道控制器扩展库OrbitControls.js
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { ref, onMounted } from 'vue';
//引入性能监视器stats.js
import Stats from 'three/addons/libs/stats.module.js';
// 定义相机输出画布的尺寸(单位:像素px)
const width = window.innerWidth; //宽度
const height = window.innerHeight; //高度

// 创建3D场景对象Scene
const scene = new THREE.Scene();
//创建一个长方体几何对象Geometry
const geometry = new THREE.CylinderGeometry(0, 0, 0); 
//创建一个材质对象Material
// const material = new THREE.MeshBasicMaterial({
//      color: 0x0000ff, //设置材质颜色
//     transparent:false,//开启透明
//     opacity:1,//设置透明度
// }); 
//MeshLambertMaterial受光照影响
const material = new THREE.MeshLambertMaterial(
    {
        color: 0x0000ff, //设置材质颜色
    }
); 

// 两个参数分别为几何体geometry、材质material
const mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh

//设置网格模型在三维空间中的位置坐标，默认是坐标原点
mesh.position.set(0,100,0);
// 在threejs中你创建了一个表示物体的虚拟对象Mesh，需要通过.add()方法，把网格模型mesh添加到三维场景scene中。
scene.add(mesh); 

// AxesHelper：辅助观察的坐标系
const axesHelper = new THREE.AxesHelper(300);
scene.add(axesHelper);

// 30:视场角度, width / height:Canvas画布宽高比, 1:近裁截面, 3000：远裁截面
const camera = new THREE.PerspectiveCamera(30, width / height, 1, 3000);
//相机在Three.js三维坐标系中的位置
// 根据需要设置相机位置具体值
camera.position.set(400, 400, 400); 

//相机观察目标指向Threejs 3D空间中某个位置
//坐标原点
//指向mesh对应的位置
camera.lookAt(mesh.position);

//点光源：两个参数分别表示光源颜色和光照强度
// 参数1：0xffffff是纯白光,表示光源颜色
// 参数2：1.0,表示光照强度，可以根据需要调整
// AmbientLight 环境光
const pointLight = new THREE.AmbientLight(0xffffff, 1.0);

//点光源位置
pointLight.position.set(100, 300, 100);//点光源放在x轴上

scene.add(pointLight); //点光源添加到场景中

// DirectionalLightHelper：可视化平行光
// const dirLightHelper = new THREE.DirectionalLightHelper(directionalLight, 5,0xff0000);
// scene.add(dirLightHelper);

// 创建渲染器对象
const renderer = new THREE.WebGLRenderer();
renderer.setSize(width, height); //设置three.js渲染区域的尺寸(像素px)
renderer.render(scene, camera); //执行渲染操作


// 设置相机控件轨道控制器OrbitControls
const controls = new OrbitControls(camera, renderer.domElement);
// 如果OrbitControls改变了相机参数，重新调用渲染器渲染三维场景
controls.addEventListener('change', function () {
    renderer.render(scene, camera); //执行渲染操作
});//监听鼠标、键盘事件



//创建stats对象
const stats = new Stats();
const webgl = ref(null)
onMounted(() => {
    webgl.value.appendChild(renderer.domElement);
    
});
// stats.domElement显示：渲染帧率  刷新频率,一秒渲染次数 
stats.setMode(0);//默认模式
//stats.domElement显示：渲染周期 渲染一帧多长时间(单位：毫秒ms)
  stats.setMode(1);

  // 随机创建大量的模型,测试渲染性能
const num = 1000; //控制长方体模型数量
for (let i = 0; i < num; i++) {
    const geometry = new THREE.BoxGeometry(5, 5, 5);
    const material = new THREE.MeshLambertMaterial({
        color: 0x00ffff
    });
    const mesh = new THREE.Mesh(geometry, material);
    // 随机生成长方体xyz坐标
    const x = (Math.random() - 0.5) * 200
    const y = (Math.random() - 0.5) * 200
    const z = (Math.random() - 0.5) * 200
    mesh.position.set(x, y, z)
    scene.add(mesh); // 模型对象插入场景中
}
// 渲染函数
function render() {
	//requestAnimationFrame循环调用的函数中调用方法update(),来刷新时间
	stats.update();
	renderer.render(scene, camera); //执行渲染操作
	requestAnimationFrame(render); //请求再次执行渲染函数render，渲染下一帧
}
render();
</script>

<style >
body{
    width: 100%;
    height: 100%;
}
.box{
     width: 100%;
    height: 100%;
}
#webgl{
    width: 100%;
    height: 100%;
}
</style>